/**
    MVP Tree data structure using graph database for I/O storage
    Copyright (C) 2014  David G. Starkweather

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    David Starkweather starkd88@gmail.com
**/

package org.phash.mvptree;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;


/**
 * Datapoint class for representing unit of
 * data in mvptree as a long datatype.
 **/
public class LongDatapoint extends Datapoint {


    public LongDatapoint(Node node){

	super(node);

    }


    public LongDatapoint(Node node, long data){

	super(node);
	setData(data);

    }

    public LongDatapoint(Datapoint point){
	
	super(point);

    }


    public void setData(long data){
	Node node = getNode();
	Transaction tx = node.getGraphDatabase().beginTx();
	try {
	    node.setProperty(DATA, data);
	    tx.success();
	} finally {
	    tx.finish();
	}
    }

    public long getData(){
	Node node = getNode();
	Transaction tx = node.getGraphDatabase().beginTx();
	long data = 0;
	try {
	    data = (long)node.getProperty(DATA);
	    tx.success();
	} finally {
	    tx.finish();
	}
	return data;
    }

    /**
     * compute L1 distance betweeen two points 
     *
     * @param point other Datapoint with which to compare
     * @return float val for distance between two points 
     *
     **/
    public float distance(Datapoint point){
	Datapoint.incrementNumOps();

	LongDatapoint pnt = (LongDatapoint)point;
	long x = this.getData();
	long y = pnt.getData();

	if (x == 0 || y == 0)
	    throw new BadDistanceValueException();

	long xord = x^y;
	return (float)Long.bitCount(xord);
    }

}